package com.zhoust.search.service.impl;

import com.github.pagehelper.PageInfo;
import com.zhoust.search.pojo.Items;
import com.zhoust.search.service.EsItemService;
import com.zhoust.utils.PagedGridResult;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 15703
 * @version 1.0
 * @Title
 * @package com.zhoust.search.service.impl
 * @date 2020/11/5 15:13
 * @desc
 */
@Service
public class EsItemServiceImpl implements EsItemService {

    @Autowired
    private ElasticsearchTemplate esTemplate;

    @Override
    public PagedGridResult searhItems(String keywords, String sort, Integer page, Integer pageSize) {


        //高亮条件
        String preTags = "<font color='red'>";
        String postTags = "</font>";

        //分页
        Pageable pageable = PageRequest.of(page,pageSize);
        //模糊查询条件
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("itemName", keywords);
        //高亮部分
        HighlightBuilder.Field highlightBuilder = new HighlightBuilder.Field("itemName")
                .preTags(preTags)
                .postTags(postTags);
        //排序

        SortBuilder sortBuilder = null;
        if("c".equals(sort)){
            sortBuilder = new FieldSortBuilder("sellCounts").order(SortOrder.ASC);
        }else if("p".equals(sort)){
            sortBuilder = new FieldSortBuilder("price").order(SortOrder.ASC);
        }else{
            //默认使用 itemName 排序
            sortBuilder = new FieldSortBuilder("itemName.keyword").order(SortOrder.ASC);
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                //模糊查询部分
                .withQuery(matchQueryBuilder)
                //高亮部分
                .withHighlightFields(highlightBuilder)
                //排序 可以多条件
                .withSort(sortBuilder)
                //分页
                .withPageable(pageable)
                .build();


        AggregatedPage<Items> stus = esTemplate.queryForPage(searchQuery, Items.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {

                SearchHits hits = searchResponse.getHits();
                //总条数
                long totalHits = hits.getTotalHits();
                SearchHit[] hitsHits = hits.getHits();
                List stuHighLights = new ArrayList();
                for (SearchHit hitsHit:hitsHits) {
                    Map<String, HighlightField> highlightFields = hitsHit.getHighlightFields();
                    HighlightField desc = highlightFields.get("itemName");
                    String itemName = desc.getFragments()[0].toString();
                    System.out.println(itemName);
                    //重构 Items 对象
                    Items items = new Items();
                    Map<String, Object> sourceAsMap = hitsHit.getSourceAsMap();
                    String itemId = (String)sourceAsMap.get("itemId");
                    String imgUrl = (String)sourceAsMap.get("imgUrl");
                    Object sellCounts = sourceAsMap.get("sellCounts");
                    Object price = sourceAsMap.get("price");
                    items.setImgUrl(imgUrl);
                    items.setItemId(itemId);
                    items.setSellCounts(Integer.valueOf(sellCounts.toString()));
                    items.setPrice(Integer.valueOf(price.toString()));
                    items.setItemName(itemName);
                    stuHighLights.add(items);
                }
                //将stuHighLights格式转换返回
                if(stuHighLights.size()>0){
                    return new AggregatedPageImpl<>((List<T>) stuHighLights);
                }
                return null;
            }
        });
        int totalPages = stus.getTotalPages();
        System.out.println("总页数："+totalPages);
        List<Items> content = stus.getContent();
        return setterPagedGrid(content,totalPages);
    }

    private PagedGridResult setterPagedGrid(List<?> list, Integer page) {
        PageInfo<?> pageList = new PageInfo<>(list);
        PagedGridResult grid = new PagedGridResult();
        grid.setPage(page);
        grid.setRows(list);
        grid.setTotal(pageList.getPages());
        grid.setRecords(pageList.getTotal());
        return grid;
    }
}
